package com.inspur.dgov.bsp.user.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.inspur.dgov.bsp.user.entity.PubOrgan;
import com.inspur.dgov.bsp.user.entity.PubRegion;
import com.inspur.dgov.bsp.user.entity.PubUser;
import com.inspur.dgov.bsp.user.service.PubOrganService;
import com.inspur.dgov.bsp.user.service.PubRegionService;
import com.inspur.dgov.bsp.user.service.PubUserService;
import com.inspur.dgov.bsp.user.service.TreeService;
import com.inspur.dgov.bsp.user.vo.OrganNode;
import com.inspur.dgov.bsp.user.vo.RegionVO;
import com.inspur.dgov.common.secure.dto.SecureUser;
import com.inspur.dgov.common.secure.utils.SecureUtil;
import com.inspur.dgov.common.tool.api.R;
import com.inspur.dgov.common.tool.constant.AppConstant;
import com.inspur.dgov.common.tool.utils.UniqueIdGenerator;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 区划信息 前端控制器
 * </p>
 *
 * @author chiyupei
 * @since 2020-04-17
 */
@RestController
@RequestMapping("/region")
@Api(value = "区划管理", tags = "区划接口")
public class PubRegionController {

    @Autowired
    private PubUserService pubUserService;

    @Autowired
    private PubRegionService pubRegionService;

    @Autowired
    private TreeService treeService;

    @Autowired
    private PubOrganService pubOrganService;

    @Value("${tenant.default.id}")
    private String defaultTenantId;

    /**
     * 区划分页列表
     *
     * @param regionId
     * @param query
     * @param page
     * @return
     */
    @PostMapping("/page")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "regionId", value = "区划ID", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "query", value = "查询条件", paramType = "query", dataType = "String")
    })
    @ApiOperation(value = "区划分页列表", notes = "传入区划ID或查询条件", position = 1)
    public R<IPage<RegionVO>> page(@RequestParam(value="regionId", required = false) String regionId,
                                   @RequestParam(value="query", required = false) String query, Page page) {
        Map<String, Object> params = new HashMap<>();
        params.put("regionId", regionId);
        params.put("query", query);

//        QueryWrapper<PubRegion> queryWrapper = null;
        if (StrUtil.isBlank(regionId)) {
            //获取最根节点(根据当前用户的所属区划获取)
            SecureUser curUser = SecureUtil.getUser();
            PubUser user = this.pubUserService.getById(curUser.getUserId());
            params.put("regionId", user.getRegionId());
//            queryWrapper = new QueryWrapper<>();
//            queryWrapper.lambda().isNull(PubRegion::getParentId);
//            PubRegion root = this.pubRegionService.getOne(queryWrapper);
//            if (null != root) {
//                params.put("regionId", root.getId());
//            }
        }

        IPage<RegionVO> pages = this.pubRegionService.selectRegionPage(page, params);
        return R.data(pages);
    }

    /**
     * 唯一性校验
     *
     * @param value
     * @param id
     * @return
     */
    @PostMapping("/verifyUnique")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "value", value = "区划编码", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "id", value = "区划ID", paramType = "query", dataType = "String")
    })
    @ApiOperation(value = "区划唯一性校验", notes = "传入区划编码和区划ID", position = 2)
    public R verifyUnique(@RequestParam(value = "value", required = true) String value,
                          @RequestParam(value = "id", required = false) String id) {
        if (StrUtil.hasEmpty(value)) {
            return R.fail("接口调用不合法");
        }

        QueryWrapper<PubRegion> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(PubRegion::getCode, value);
        if (StrUtil.isNotEmpty(id)) {
            queryWrapper.lambda().ne(PubRegion::getId, id);
        }

        //查出满足条件的所有记录
        List<PubRegion> list = this.pubRegionService.list(queryWrapper);
        if (ObjectUtil.isEmpty(list)) {
            return R.success("");
        }
        return R.fail("该区划编码已被使用");
    }

    /**
     * 新增区划
     *
     * @param region
     * @return
     */
    @PostMapping("/add")
    @ApiOperation(value = "新增区划", notes = "传入区划信息", position = 3)
    public R add(@RequestBody PubRegion region) {
        SecureUser curUser = SecureUtil.getUser();
        Long id = UniqueIdGenerator.generateId();
        //check是否已有根节点
        QueryWrapper<PubRegion> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().isNull(PubRegion::getParentId);
        PubRegion root = this.pubRegionService.getOne(queryWrapper);
        if (null != root) {
            if (ObjectUtil.isNull(region.getParentId())) {
                return R.fail("请选择上级区划");
            }
        } else {
            PubUser user = this.pubUserService.getById(curUser.getUserId());
            id = user.getRegionId();
        }

        LocalDateTime now = LocalDateTime.now();
        region.setId(id);
        region.setCreator(Long.valueOf(curUser.getUserId()));
        region.setCreateTime(now);
        region.setStatus(AppConstant.DB_STATUS_NORMAL);
        boolean ret = this.pubRegionService.saveRegion(region);
        return R.status(ret);
    }

    /**
     * 更新区划
     *
     * @param region
     * @return
     */
    @PostMapping("/update")
    @ApiOperation(value = "更新区划", notes = "传入区划信息", position = 4)
    public R update(@RequestBody PubRegion region) {
        SecureUser curUser = SecureUtil.getUser();
        //判断是否更改父节点
        PubRegion pubOrgan = this.pubRegionService.getById(region.getId());
        Long newParentId = region.getParentId();
        if (null != newParentId) {
            if (newParentId == pubOrgan.getId()) {
                return R.fail("上级区划不能选择自身");
            }
            //父节点变更
            if (!newParentId.equals(pubOrgan.getParentId())) {
                this.pubRegionService.moveRegion(region);
            }
        }
        LocalDateTime now = LocalDateTime.now();
        region.setUpdator(Long.valueOf(curUser.getUserId()));
        region.setUpdateTime(now);
        boolean ret = this.pubRegionService.updateById(region);
        return R.status(ret);
    }

    /**
     * 删除区划
     * @param region
     * @return
     */
    @PostMapping("/remove")
    @ApiOperation(value = "删除区划", notes = "传入区划信息", position = 5)
    public R remove(@RequestBody PubRegion region) {
        //检查是否有下级
        QueryWrapper<PubRegion> regionWrapper = new QueryWrapper<>();
        regionWrapper.lambda().eq(PubRegion::getParentId, region.getId());
        int regionCount = this.pubRegionService.count(regionWrapper);
        if (regionCount > 0) {
            return R.fail("存在下级区划，不能删除");
        }
        //检查区划下是否有单位
        QueryWrapper<PubOrgan> organWrapper = new QueryWrapper<>();
        organWrapper.lambda().eq(PubOrgan::getRegionId, region.getId());
        int organCount = this.pubOrganService.count(organWrapper);
        if (organCount > 0) {
            return R.fail("存在下级组织，不能删除");
        }
        boolean ret = this.pubRegionService.deleteRegion(region);
        return R.status(ret);
    }

    /**
     * 子级区划树
     */
    @GetMapping("/regionTree")
    @ApiOperation(value = "子级区划树", notes = "区划树", position = 6)
    public R<List<OrganNode>> regionTree(@ApiParam(value = "区划ID") @RequestParam(value="regionId", required = false) String regionId) {
        List<OrganNode> tree = new ArrayList<>();
//        QueryWrapper<PubRegion> queryWrapper = null;
        PubRegion root;
        if (StrUtil.isBlank(regionId)) {
            //获取最根节点(根据当前用户的所属区划获取)
            SecureUser curUser = SecureUtil.getUser();
            PubUser user = this.pubUserService.getById(curUser.getUserId());
            root = new PubRegion();
            root.setId(user.getRegionId());
//            queryWrapper = new QueryWrapper<>();
//            queryWrapper.isNull("parent_id");
//            root = this.pubRegionService.getOne(queryWrapper);
        } else {
            root = new PubRegion();
            root.setId(Long.valueOf(regionId));
        }

        if (null != root && null != root.getId()) {
            tree = this.treeService.regionTree(root);
        }
        return R.data(tree);
    }

}
